/*
 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 */

package java.util;

/**
 * <p>一个包含不重复元素的集合。
 * 更正式地说，set不包含这样的元素对，e1和e2，e1.equals(e2)，并且最大有一个null元素。
 * 顾名思义，该接口对数学集抽象进行建模。
 * 
 * <p>Set接口在从Collection接口继承来的方法，对所有的构造器，add，equals，hashCode方法，有着额外的约定。
 * 为了方便起见，这里还包含了其他继承方法的声明。(伴随这些声明的规范是针对Set接口定制的，但是它们不包含任何额外的规定。)
 * 
 * <p>关于构造器的额外规定是，所有的构造器必须创造一个不包含重复元素的set。
 * 
 * <p>注意：如果使用可变对象作为set的元素，必须十分小心。
 * 如果一个对象的值改变了，影响了equals的比较，同时是set的一个元素，set的行为没有被规定。
 * 禁止的一个特殊情况是不允许set中，不允许把自己作为一个元素。
 * 
 * <p>一些set的实现可能对可以包含的元素有限制。
 * 例如一些实现禁止null元素，一些对元素的类型有限制。
 * 尝试加入一个非法的元素会抛出未检查异常，通常是NullPointerException，ClassCastException。
 * 尝试查询非法元素的存在可能抛出异常，或者紧急返回false。
 * 一些实现会显示前一种行为，一些显示后面的行为。
 * 更一般地说，尝试对不符合条件的元素执行操作，而该元素的完成不会导致将不符合条件的元素插入到set中，这可能会引发异常，
 * 也可能会成功，取决于实现的选择。在这个接口的规范中，这些异常被标记为“可选”。
 *
 * @param <E> the type of elements maintained by this set
 *
 * @author  Josh Bloch
 * @author  Neal Gafter
 * @see Collection
 * @see List
 * @see SortedSet
 * @see HashSet
 * @see TreeSet
 * @see AbstractSet
 * @see Collections#singleton(java.lang.Object)
 * @see Collections#EMPTY_SET
 * @since 1.2
 */

public interface Set<E> extends Collection<E> {
    // Query Operations

    /**
     * 返回集合中元素的数量。如果set包含超过Integer.MAX_VALUE的元素，返回Integer.MAX_VALUE
     *
     * @return the number of elements in this set (its cardinality)
     */
    int size();

    /**
     * 如果set不包含任何元素，返回true
     *
     * @return <tt>true</tt> if this set contains no elements
     */
    boolean isEmpty();

    /**
     * 如果set包含指定元素，返回true。
     * 更正式地，当且仅当集合至少有一个这样的元素时，返回true。
     * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>.
     *
     * @param o element whose presence in this set is to be tested
     * @return <tt>true</tt> if this set contains the specified element
     * @throws ClassCastException if the type of the specified element
     *         is incompatible with this set
     * (<a href="Collection.html#optional-restrictions">optional</a>)
     * @throws NullPointerException if the specified element is null and this
     *         set does not permit null elements
     * (<a href="Collection.html#optional-restrictions">optional</a>)
     */
    boolean contains(Object o);

    /**
     * 返回一个覆盖这个set所有元素的iterator。
     * 不保证元素返回的顺序（除非set是一些提供保证的类的实例）
     *
     * @return an iterator over the elements in this set
     */
    Iterator<E> iterator();

    /**
     * 返回一个包含这个set所有元素的数组。
     * 如果set保证由它的iterator返回的元素的顺序，这个方法必须以同样的顺序返回这些元素。
     *
     * <p>返回的数组是安全的，因为set没有维持对它的引用
     * （换言而之，这个方法必须分配一个新的数组，即使set内部已经有一个数组了）。
     * 因此调用者修改返回的数组是安全的。
     *
     * <p>这个方法是基于数组和基于集合的API之间的桥梁。
     *
     * @return an array containing all the elements in this set
     */
    Object[] toArray();

    /**
     * <p>返回一个包含这个set所有元素的数组。
     * 返回的数组的运行时类型是指定数组的烈性。
     * 如果set适合这个指定的数组的大小，她就在里面返回。
     * 否则，创建一个新数组，类型为指定数组的运行时类型，大小为这个set的大小。
     * 
     * <p>如果该set适应指定的数组，有着剩余的空间（数组比set有更多的元素），
     * 数组中的元素在set的末尾的，被设置为null。
     * （如果调用者知道set确实没有任何null元素，这才有助于决定set的长度）
     * 
     * <p>如果set保证由它的iterator返回的元素的顺序，这个方法必须以同样的顺序返回这些元素。
     * 
     * <p>像toArray()方法，这个方法作为基于数组和基于set的API之间的桥梁。
     * 此外，这个方法允许对输出的数组的运行时类型做出精确的控制。
     * 在某些情况下，可能有助于减少分配的成本。
     * 
     * <p>假设x是一个只能包含string的set。
     * 下面的代码能用于将set放入一个新分配的string数组。
     * 
     * <pre>
     *     String[] y = x.toArray(new String[0]);</pre>
     *
     * 注意：toArray(new Object[0])等价于toArray()的功能
     *
     * @param a the array into which the elements of this set are to be
     *        stored, if it is big enough; otherwise, a new array of the same
     *        runtime type is allocated for this purpose.
     * @return an array containing all the elements in this set
     * @throws ArrayStoreException if the runtime type of the specified array
     *         is not a supertype of the runtime type of every element in this
     *         set
     * @throws NullPointerException if the specified array is null
     */
    <T> T[] toArray(T[] a);


    // Modification Operations

    /**
     * <p>如果set没有指定元素，将指定元素加入set（可选的操作）。
     * 更正式地说，如果set不包含元素e2，有指定元素e，
     * <tt>(e==null&nbsp;?&nbsp;e2==null&nbsp;:&nbsp;e.equals(e2))</tt>
     * 将e加入到set。
     * 
     * <p>如果set已经包含了这个元素，调用让set不改变，并且返回false。
     * 与构造器的限制结合在一起，这保证set不包含重复的元素。
     * 
     * <p>这个限制没有暗示set必须包含所有的元素。
     * set可以拒绝包含任何额外的元素，包括null，然后抛出一个异常，如Collection的add方法的规定。
     * 单独的set实现应该清楚地报告可以包含的元素的限制。
     *
     * @param e element to be added to this set
     * @return <tt>true</tt> if this set did not already contain the specified
     *         element
     * @throws UnsupportedOperationException if the <tt>add</tt> operation
     *         is not supported by this set
     * @throws ClassCastException if the class of the specified element
     *         prevents it from being added to this set
     * @throws NullPointerException if the specified element is null and this
     *         set does not permit null elements
     * @throws IllegalArgumentException if some property of the specified element
     *         prevents it from being added to this set
     */
    boolean add(E e);


    /**
     * 如果指定元素存在，从set中移除指定元素（可选的操作）。
     * 更正式地说，如果set包含一个这样的元素，就移除一个这样的元素 ，
     * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>
     * 如果集合包含指定元素，返回true。（如果集合因为调用而改变，返回true）
     * (调用结束后，set不会包含这个元素）
     *
     * @param o object to be removed from this set, if present
     * @return <tt>true</tt> if this set contained the specified element
     * @throws ClassCastException if the type of the specified element
     *         is incompatible with this set
     * (<a href="Collection.html#optional-restrictions">optional</a>)
     * @throws NullPointerException if the specified element is null and this
     *         set does not permit null elements
     * (<a href="Collection.html#optional-restrictions">optional</a>)
     * @throws UnsupportedOperationException if the <tt>remove</tt> operation
     *         is not supported by this set
     */
    boolean remove(Object o);


    // Bulk Operations

    /**
     * 如果set包含指定集合中所有的元素，返回true。
     * 如果指定集合也是一个set，如果指定集合是这个set的subset，这个方法返回true。
     *
     * @param  c collection to be checked for containment in this set
     * @return <tt>true</tt> if this set contains all of the elements of the
     *         specified collection
     * @throws ClassCastException if the types of one or more elements
     *         in the specified collection are incompatible with this
     *         set
     * (<a href="Collection.html#optional-restrictions">optional</a>)
     * @throws NullPointerException if the specified collection contains one
     *         or more null elements and this set does not permit null
     *         elements
     * (<a href="Collection.html#optional-restrictions">optional</a>),
     *         or if the specified collection is null
     * @see    #contains(Object)
     */
    boolean containsAll(Collection<?> c);

    /**
     * 将指定集合的所有元素加入到这个set，如果它们原来不在（可选操作）。
     * 如果指定集合也是一个set，addAll操作有效地修改这个set，如果两个set进行union（并集 AUB）操作。
     * 当执行操作时，如果修改指定集合，操作的结果未知。
     *
     * @param  c collection containing elements to be added to this set
     * @return <tt>true</tt> if this set changed as a result of the call
     *
     * @throws UnsupportedOperationException if the <tt>addAll</tt> operation
     *         is not supported by this set
     * @throws ClassCastException if the class of an element of the
     *         specified collection prevents it from being added to this set
     * @throws NullPointerException if the specified collection contains one
     *         or more null elements and this set does not permit null
     *         elements, or if the specified collection is null
     * @throws IllegalArgumentException if some property of an element of the
     *         specified collection prevents it from being added to this set
     * @see #add(Object)
     */
    boolean addAll(Collection<? extends E> c);

    /**
     * 只保留指定集合包含的元素。（可选操作）。
     * 换言而之，移除所有不被指定集合包含的元素。
     * 如果指定集合也是一个set，这个操作有效地修改这个集合，执行两个set的交集(ANB)操作。
     *
     * @param  c collection containing elements to be retained in this set
     * @return <tt>true</tt> if this set changed as a result of the call
     * @throws UnsupportedOperationException if the <tt>retainAll</tt> operation
     *         is not supported by this set
     * @throws ClassCastException if the class of an element of this set
     *         is incompatible with the specified collection
     * (<a href="Collection.html#optional-restrictions">optional</a>)
     * @throws NullPointerException if this set contains a null element and the
     *         specified collection does not permit null elements
     *         (<a href="Collection.html#optional-restrictions">optional</a>),
     *         or if the specified collection is null
     * @see #remove(Object)
     */
    boolean retainAll(Collection<?> c);

    /**
     * 删除这个set中，所有已经包含在指定集合的元素（可选操作）。
     * 如果指定集合也是一个set，这个集合的结果是两个集合的不对称差异。
     *
     * @param  c collection containing elements to be removed from this set
     * @return <tt>true</tt> if this set changed as a result of the call
     * @throws UnsupportedOperationException if the <tt>removeAll</tt> operation
     *         is not supported by this set
     * @throws ClassCastException if the class of an element of this set
     *         is incompatible with the specified collection
     * (<a href="Collection.html#optional-restrictions">optional</a>)
     * @throws NullPointerException if this set contains a null element and the
     *         specified collection does not permit null elements
     *         (<a href="Collection.html#optional-restrictions">optional</a>),
     *         or if the specified collection is null
     * @see #remove(Object)
     * @see #contains(Object)
     */
    boolean removeAll(Collection<?> c);

    /**
     * 移除set中所有的元素（可选操作）。这个方法返回后，set为空。
     *
     * @throws UnsupportedOperationException if the <tt>clear</tt> method
     *         is not supported by this set
     */
    void clear();


    // Comparison and hashing

    /**
     * 将指定对象与这个set，进行相等性的比较。
     * 如果指定对象也是一个set，两个set有相同的大小，指定set的每个成员，都被这个set包含
     * （相同的，这个set的每个成员，都被指定set包含），返回true。
     * 这个定义保证equals方法在不同set接口的实现中，工作正常。
     *
     * @param o object to be compared for equality with this set
     * @return <tt>true</tt> if the specified object is equal to this set
     */
    boolean equals(Object o);

    /**
     * 返回这个set的hashcode。
     * set的hashcode与这个set中元素的hashcode的和相同。
     * null元素的hashcode为0.
     * 这保证对于两个set，s1和s2，s1.equals(s2)
     * 意味着s1.hashCode()==s2.hashCode()，如Object的hashcode的通常约定。
     *
     * @return the hash code value for this set
     * @see Object#equals(Object)
     * @see Set#equals(Object)
     */
    int hashCode();

    /**
     * 创建一个覆盖这个集合的元素的spliterator
     *
     * <p>实现的spliterator应该报告DISTINCT和额外的特征值。
     *
     * <p>默认的实现创建了一个迟绑定的spliterator，根据set的Iterator。
     * 这个spliterator继承了set的Iterator的快速失败属性。
     * 
     * <p>创建的spliterator额外报告SIZED
     *
     * <p>创建的spliterator额外报告SUBSIZED
     *
     * @return a {@code Spliterator} over the elements in this set
     * @since 1.8
     */
    @Override
    default Spliterator<E> spliterator() {
        return Spliterators.spliterator(this, Spliterator.DISTINCT);
    }
}
